package com.atguigu.self.config;

import com.atguigu.self.aspect.CacheAspect;
import com.atguigu.self.constant.CacheAbleConstant;
import com.atguigu.self.service.impl.CacheOpsServiceImpl;
import org.redisson.Redisson;
import org.redisson.api.RBloomFilter;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.data.redis.RedisProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.data.redis.core.StringRedisTemplate;



@Configuration
@Import(CacheOpsServiceImpl.class)
public class CacheAbleAutoConfiguration {


    @Autowired
    private RedisProperties redisProperties;


    @Autowired
    private StringRedisTemplate redisTemplate;


    /**
     * 定义Redisson的客户端
     *
     * @return
     */
    @Bean
    public RedissonClient redissonClient() {

        Config config = new Config();
        config.useSingleServer().setAddress(CacheAbleConstant.REDIS_CACHE_PROTOCOL + redisProperties.getHost() + CacheAbleConstant.REDIS_CACHE_PROTOCOL_SPLIT + redisProperties.getPort());
        return Redisson.create(config);
    }

    /**
     * 定义分布式布隆过滤器
     */

    @Bean
    public RBloomFilter rBloomFilter(RedissonClient redissonClient) {
        // 1.获取到布隆过滤器（第一次会创建一个新的 后面可以直接用）
        Boolean aBoolean = redisTemplate.opsForValue().setIfAbsent(CacheAbleConstant.DISTRO_BLOOM_LOCK_KEY, CacheAbleConstant.DISTRO_BLOOM_LOCK_FLAG); // 主要保证幂等性（只有第一次才能完成布隆的初始化，后面服务不管重启多少次 都不会继续初始化）
        RBloomFilter<Object> bloomFilter = redissonClient.getBloomFilter(CacheAbleConstant.DISTRO_BLOOM_NAME);
        if (Boolean.TRUE.equals(aBoolean)) {
            // 2.初始化布隆过滤器
            bloomFilter.tryInit(CacheAbleConstant.DISTRO_BLOOM_SIZE, CacheAbleConstant.DISTRO_BLOOM_FPP);
            return bloomFilter;
        } else {
            // 3.返回布隆过滤器对象
            return bloomFilter;
        }
    }

    /**
     * 定义一个切面
     */

    @Bean
    public CacheAspect cacheAspect() {

        return new CacheAspect();
    }

}
